﻿/***************************************************************
 * 开发人员：网魂小兵@http://www.mozlite.com
 * 
 * 数据库提供者配置类。
 * 
 * 最后修改：2011-10-25
 * ************************************************************/
namespace Mozlite.Configuration
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;
    using System.IO;
    using System.Web.Caching;
    using System.Web;
    using Mozlite.Caching;

    /// <summary>
    /// 数据库提供者配置。
    /// </summary>
    public class DataProviders
    {
        static DataProviders()
        {
            configFilePath = CommonHelper.MapPath("~/Database.config");
        }

        private static readonly string cacheKey = "Mozlite.Configuration.DataProviders.AllProviders";

        private DataProviders(XmlDocument doc)
        {
            this.doc = doc;
            XmlNode root = doc.SelectSingleNode("configuration");
            foreach (XmlNode node in root)
            {
                if (node.NodeType == XmlNodeType.Comment)
                    continue;
                if (node.Name == "default")
                    providerName = node.GetInnerText("sqlserver");
                else if (node.Name == "provider")
                    providers.Add(node.GetAttribute("name", null), new DataProvider(node));
            }
        }
        /// <summary>
        /// 获取数据提供者列表。
        /// </summary>
        /// <returns>返回数据提供者列表。</returns>
        public static DataProviders GetProviders() {
            return Cacher.Get<DataProviders>(cacheKey, () =>
            {
                if (!File.Exists(configFilePath))
                    throw new FileNotFoundException("Database config file is not existed in the site root path!", "Database.config");
                XmlDocument doc = new XmlDocument();
                doc.Load(configFilePath);
                var providers = new DataProviders(doc);
                Cacher.Max(cacheKey, providers, Dependency);
                return providers;
            });
        }

        private string providerName;
        private static readonly string configFilePath;
        private XmlDocument doc;
        Dictionary<string, DataProvider> providers = new Dictionary<string, DataProvider>(StringComparer.OrdinalIgnoreCase);
        /// <summary>
        /// 获取数据库提供者的名称集合。
        /// </summary>
        public Dictionary<string, DataProvider>.KeyCollection ProviderNames
        {
            get
            {
                return providers.Keys;
            }
        }
        /// <summary>
        /// 索引获取数据库提供者对象。
        /// </summary>
        /// <param name="name">索引名称。</param>
        /// <returns>返回数据库提供者对象。</returns>
        public DataProvider this[string name]
        {
            get
            {
                DataProvider provider;
                if (providers.TryGetValue(name, out provider))
                    return provider;
                return null;
            }
        }
        /// <summary>
        /// 获取当前数据库提供者。
        /// </summary>
        public DataProvider Current
        {
            get
            {
                return this[providerName];
            }
        }
        /// <summary>
        /// 选择匹配XPath路径的第一个节点。
        /// </summary>
        /// <param name="xpath">XPath路径。</param>
        /// <returns>返回匹配XPath路径的第一个节点。</returns>
        public XmlNode SelectSingleNode(string xpath)
        {
            return this.doc.SelectSingleNode(xpath);
        }
        /// <summary>
        /// 通过名称创建一个节点。
        /// </summary>
        /// <param name="name">节点名称。</param>
        /// <returns>返回创建一个节点。</returns>
        public XmlElement CreateElement(string name)
        {
            return this.doc.CreateElement(name);
        }
        /// <summary>
        /// 保存到配置文件。
        /// </summary>
        public void Save()
        {
            this.doc.Save(configFilePath);
        }
        /// <summary>
        /// 获取配置文件缓存依赖项。
        /// </summary>
        public static CacheDependency Dependency
        {
            get { return new CacheDependency(configFilePath); }
        }
    }
}
